﻿/**************************************************************
 * St. Sana - A file/folder scanner originall designed for    *
 * Open Media Library (open-media-library.googlecode.com)     *
 *                                                            *
 * Available for use by ANY project that wants to use it.     *
 * St. Sana is covered by the Apache 2 license.               *
 * Feel free to use this software however you like so as long *
 * as you follow the guidelines of above mentioned license.   *
 * Written by David J. Shultz (djshultz@gmail.com)            *
 **************************************************************/

using System;
using System.IO;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace StSana
{
    public class Serf
    {
        public enum EntityType
        {
            UNKNOWN,
            TV_SHOW,
            MOVIE,
            COLLECTION
        };

        public enum DiscType
        {
            UNKNOWN,
            BLURAY_FOLDER,
            BLURAY_FILES,
            DVD_FOLDER,
            DVD_FILES,
            HDDVD_FOLDER
        };

        public struct EpisodeData
        {
            public int SeasonNumber;
            public List<int> EpisodeNumber;
        }

        static public EpisodeData getEpisodeDataForPath(string path)
        {
            EpisodeData ed = new EpisodeData();
            ed.EpisodeNumber = new List<int>();
            bool matched = false;
            foreach (Regex rx in TVEpisodeRegularExpressions)
            {
                if (matched == false)
                {
                    Match m = rx.Match(path);
                    if (m.Success)
                    {
                        int epNo = -1;
                        if (m.Groups["Episode"].Captures.Count > 1)
                        { // its more then 1 episode
                            for (int i = 0; i < m.Groups["Episode"].Captures.Count; i++)
                            {
                                Int32.TryParse(m.Groups["Episode"].Captures[i].Value, out epNo);
                                ed.EpisodeNumber.Add(epNo);
                                epNo = -1;
                            }
                            
                        }
                        else
                        {
                            Int32.TryParse(m.Groups["Episode"].Value, out epNo);
                            if (epNo > -1)
                                ed.EpisodeNumber.Add(epNo);
                        }

                        int seNo = -1;
                        Int32.TryParse(m.Groups["Season"].Value, out seNo);
                        if (seNo > -1)
                            ed.SeasonNumber = seNo;

                        matched = true;
                    }
                }
            }
            return ed;
        }

        static public string GetShowNameFromSSFile(SSFile file)
        {
            return "";
        }

        static public DiscType getDiscType(string path)
        {
            if (ContainsBDMVSubFolder(path))
                return DiscType.BLURAY_FOLDER;

            if (ContainsBlurayFilesWithoutBDMVFolder(path))
                return DiscType.BLURAY_FILES;

            if (ContainsHDDVDSubFolder(path))
                return DiscType.HDDVD_FOLDER;

            if (ContainsVideoTSSubFolder(path))
                return DiscType.DVD_FOLDER;

            if (ContainsDVDFilesWithoutVideoTSFolder(path))
                return DiscType.DVD_FILES;
            return DiscType.UNKNOWN;
        }
        /// <summary>
        /// IList of known/acceptable video file extensions
        /// </summary>
        static IList<string> ValidVideoExtensions = new List<string>()
        {
            "ASF",      // WMV style
            "AVC",      // AVC H264
            "AVI",      // DivX, Xvid, etc
            "DIVX",     // DivX
            "DVR-MS",   // MPG (Windows Media Center Pre-Win7/Vista w/TV Pack)
            "H264",     // AVC OR MP4
            "M2TS",     // mpeg2 transport stream
            "MKV",      // Likely h264
            "MOV",      // apple quicktime
            "MP4",      // DivX, AVC, or H264
            "MPG",      // mpeg
            "MPEG",     // mpeg
            "OGM",      // Similar to MKV
            "TS",       // MPEG2 (transport stream)
            "VOB",      // MPEG2 (dvd video file)
            "WMV",      // windows media file
            "WTV",      // MPG (Windows Media Center Win7/Vista w/TV Pack)
            "WVX",      // windows playlist file (usually online streaming content)
        };

        /// <summary>
        /// IList if Regex Objects to be used for processing filenames
        /// </summary>
        static IList<Regex> TVEpisodeRegularExpressions = new List<Regex>()
        {
            // Translucent wrote this regex on 08/08/2009
            // It should handle lots of different types
            // the following formats have been tested as working:
            // Lost.1x02-03.avi, LostS1E3.4.avi, S01E01.avi, 24.2x13.avi, 
            // Greys AnatomyS04E12.avi, 04S12 - blah.avi, Lost 1E00 - blah.avi
            new Regex(@"(?<Season>\d{1,3})\s?[x|e|-](?<Episode>\d{1,3})(?:\s?[-|\.]\s?(?<Episode>\d{1,3}))?", RegexOptions.IgnoreCase)
        };

        /// <summary>
        /// Checks to see if the given filename matches one of our know regular expressions
        /// </summary>
        /// <param name="filename"></param>
        /// <returns>True if the filename matches one of our Regular Expressions</returns>
        static public bool IsValidTVEpisode(string filename)
        {
            foreach (Regex rx in TVEpisodeRegularExpressions)
            {
                Match m = rx.Match(filename);
                if (m.Success)
                    return true;
            }
            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        static public int NumberOfEpisodesInFile(string filename)
        {
            return 1;
        }

        /// <summary>
        /// Checks if the given file extension is a valid video extension
        /// </summary>
        /// <param name="extension">file extension (without a leading '.')</param>
        /// <returns>True if the file extension is valid</returns>
        static public bool IsValidVideoExtension(string extension)
        {
            return ValidVideoExtensions.Contains(extension.ToUpperInvariant()) ? true : false;
        }

        /// <summary>
        /// Checks is the given path contains a video_ts subfolder
        /// </summary>
        /// <param name="path">full path to a directory</param>
        /// <returns>True if the given directory contains a subfolder called video_ts</returns>
        static public bool ContainsVideoTSSubFolder(string path)
        {
            return (Directory.Exists(path) && Directory.Exists(Path.Combine(path, "video_ts"))) ? true : false;
        }

        /// <summary>
        /// Checks if the given path contains a video_ts.ifo file (and thus is likely to be raw dvd files)
        /// </summary>
        /// <param name="path">full path to a directory</param>
        /// <returns>True if the given path contains a video_ts.ifo file</returns>
        static public bool ContainsDVDFilesWithoutVideoTSFolder(string path)
        {
            return (Directory.Exists(path) && File.Exists(Path.Combine(path, "video_ts.ifo"))) ? true : false;
        }

        /// <summary>
        /// Checks if the given path contains a BDMV subfolder (and thus is likely to be a ripped bluray disc)
        /// </summary>
        /// <param name="path">full path to a directory</param>
        /// <returns>True if the path contains a BDMV subfolder</returns>
        static public bool ContainsBDMVSubFolder(string path)
        {
            return (Directory.Exists(path) && Directory.Exists(Path.Combine(path, "BDMV"))) ? true : false;
        }

        /// <summary>
        /// Checks if the given path contains an index.bdmv file (and thus is likely to be raw bluray files)
        /// </summary>
        /// <param name="path">full path to a directory</param>
        /// <returns>True if the given path contains an index.bdmv file</returns>
        static public bool ContainsBlurayFilesWithoutBDMVFolder(string path)
        {
            return (Directory.Exists(path) && File.Exists(Path.Combine(path, "index.bdmv"))) ? true : false;
        }

        /// <summary>
        /// Checks if the given path contains an HVDVD_TS subfolder (and thus is a ripped hddvd disc)
        /// </summary>
        /// <param name="path">full path to a directory</param>
        /// <returns>True if the given path contains a HVDVD_TS subfolder</returns>
        static public bool ContainsHDDVDSubFolder(string path)
        {
            return (Directory.Exists(path) && Directory.Exists(Path.Combine(path, "HVDVD_TS"))) ? true : false;
        }
    }
}
